home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / samples.tk / nurb.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  7KB  |  351 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <GL/gl.h>
  29. #include <GL/glu.h>
  30. #include <math.h>
  31. #include <GL/gltk.h>
  32.  
  33. #define INREAL float
  34.  
  35. #define S_NUMPOINTS 13
  36. #define S_ORDER     3
  37. #define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
  38. #define T_NUMPOINTS 3
  39. #define T_ORDER     3
  40. #define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
  41. #define SQRT_TWO    1.41421356237309504880
  42.  
  43. typedef INREAL Point[4];
  44.  
  45. GLenum doubleBuffer, directRender;
  46.  
  47. GLenum expectedError;
  48. GLint rotX = 40, rotY = 40;
  49. INREAL sknots[S_NUMKNOTS] =
  50. {
  51.   -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
  52.   4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
  53. };
  54. INREAL tknots[T_NUMKNOTS] =
  55. {
  56.   1.0, 1.0, 1.0, 2.0, 2.0, 2.0
  57. };
  58. Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] =
  59. {
  60.   {
  61.     {
  62.       4.0, 2.0, 2.0, 1.0
  63.     },
  64.     {
  65.       4.0, 1.6, 2.5, 1.0
  66.     },
  67.     {
  68.       4.0, 2.0, 3.0, 1.0
  69.     }
  70.   },
  71.   {
  72.     {
  73.       5.0, 4.0, 2.0, 1.0
  74.     },
  75.     {
  76.       5.0, 4.0, 2.5, 1.0
  77.     },
  78.     {
  79.       5.0, 4.0, 3.0, 1.0
  80.     }
  81.   },
  82.   {
  83.     {
  84.       6.0, 5.0, 2.0, 1.0
  85.     },
  86.     {
  87.       6.0, 5.0, 2.5, 1.0
  88.     },
  89.     {
  90.       6.0, 5.0, 3.0, 1.0
  91.     }
  92.   },
  93.   {
  94.     {
  95.       SQRT_TWO * 6.0, SQRT_TWO * 6.0, SQRT_TWO * 2.0, SQRT_TWO
  96.     },
  97.     {
  98.       SQRT_TWO * 6.0, SQRT_TWO * 6.0, SQRT_TWO * 2.5, SQRT_TWO
  99.     },
  100.     {
  101.       SQRT_TWO * 6.0, SQRT_TWO * 6.0, SQRT_TWO * 3.0, SQRT_TWO
  102.     }
  103.   },
  104.   {
  105.     {
  106.       5.2, 6.7, 2.0, 1.0
  107.     },
  108.     {
  109.       5.2, 6.7, 2.5, 1.0
  110.     },
  111.     {
  112.       5.2, 6.7, 3.0, 1.0
  113.     }
  114.   },
  115.   {
  116.     {
  117.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 2.0, SQRT_TWO
  118.     },
  119.     {
  120.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 2.5, SQRT_TWO
  121.     },
  122.     {
  123.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 3.0, SQRT_TWO
  124.     }
  125.   },
  126.   {
  127.     {
  128.       4.0, 5.2, 2.0, 1.0
  129.     },
  130.     {
  131.       4.0, 4.6, 2.5, 1.0
  132.     },
  133.     {
  134.       4.0, 5.2, 3.0, 1.0
  135.     }
  136.   },
  137.   {
  138.     {
  139.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 2.0, SQRT_TWO
  140.     },
  141.     {
  142.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 2.5, SQRT_TWO
  143.     },
  144.     {
  145.       SQRT_TWO * 4.0, SQRT_TWO * 6.0, SQRT_TWO * 3.0, SQRT_TWO
  146.     }
  147.   },
  148.   {
  149.     {
  150.       2.8, 6.7, 2.0, 1.0
  151.     },
  152.     {
  153.       2.8, 6.7, 2.5, 1.0
  154.     },
  155.     {
  156.       2.8, 6.7, 3.0, 1.0
  157.     }
  158.   },
  159.   {
  160.     {
  161.       SQRT_TWO * 2.0, SQRT_TWO * 6.0, SQRT_TWO * 2.0, SQRT_TWO
  162.     },
  163.     {
  164.       SQRT_TWO * 2.0, SQRT_TWO * 6.0, SQRT_TWO * 2.5, SQRT_TWO
  165.     },
  166.     {
  167.       SQRT_TWO * 2.0, SQRT_TWO * 6.0, SQRT_TWO * 3.0, SQRT_TWO
  168.     }
  169.   },
  170.   {
  171.     {
  172.       2.0, 5.0, 2.0, 1.0
  173.     },
  174.     {
  175.       2.0, 5.0, 2.5, 1.0
  176.     },
  177.     {
  178.       2.0, 5.0, 3.0, 1.0
  179.     }
  180.   },
  181.   {
  182.     {
  183.       3.0, 4.0, 2.0, 1.0
  184.     },
  185.     {
  186.       3.0, 4.0, 2.5, 1.0
  187.     },
  188.     {
  189.       3.0, 4.0, 3.0, 1.0
  190.     }
  191.   },
  192.   {
  193.     {
  194.       4.0, 2.0, 2.0, 1.0
  195.     },
  196.     {
  197.       4.0, 1.6, 2.5, 1.0
  198.     },
  199.     {
  200.       4.0, 2.0, 3.0, 1.0
  201.     }
  202.   }
  203. };
  204. GLUnurbsObj *theNurbs;
  205.  
  206. static void ErrorCallback(GLenum which)
  207. {
  208.  
  209.   if (which != expectedError) {
  210.     fprintf(stderr, "Unexpected error occured (%d):\n", which);
  211.     fprintf(stderr, "    %s\n", gluErrorString(which));
  212.   }
  213. }
  214.  
  215. static void Init(void)
  216. {
  217.  
  218.   theNurbs = gluNewNurbsRenderer();
  219.   gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
  220.  
  221.   gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
  222.   gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
  223.  
  224.   expectedError = GLU_INVALID_ENUM;
  225.   gluNurbsProperty(theNurbs, ~0, 15.0);
  226.   expectedError = GLU_NURBS_ERROR13;
  227.   gluEndSurface(theNurbs);
  228.   expectedError = 0;
  229.  
  230.   glColor3f(1.0, 1.0, 1.0);
  231. }
  232.  
  233. static void Reshape(int width, int height)
  234. {
  235.  
  236.   glViewport(0, 0, (GLint) width, (GLint) height);
  237.  
  238.   glMatrixMode(GL_PROJECTION);
  239.   glLoadIdentity();
  240.   glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
  241.   gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
  242.   glMatrixMode(GL_MODELVIEW);
  243. }
  244.  
  245. static GLenum Key(int key, GLenum mask)
  246. {
  247.  
  248.   switch (key) {
  249.     case TK_ESCAPE:
  250.       tkQuit();
  251.     case TK_DOWN:
  252.       rotX -= 5;
  253.       break;
  254.     case TK_UP:
  255.       rotX += 5;
  256.       break;
  257.     case TK_LEFT:
  258.       rotY -= 5;
  259.       break;
  260.     case TK_RIGHT:
  261.       rotY += 5;
  262.       break;
  263.     default:
  264.       return GL_FALSE;
  265.   }
  266.   return GL_TRUE;
  267. }
  268.  
  269. static void Draw(void)
  270. {
  271.  
  272.   glClear(GL_COLOR_BUFFER_BIT);
  273.  
  274.   glPushMatrix();
  275.  
  276.   glTranslatef(4.0, 4.5, 2.5);
  277.   glRotatef(rotY, 1, 0, 0);
  278.   glRotatef(rotX, 0, 1, 0);
  279.   glTranslatef(-4.0, -4.5, -2.5);
  280.  
  281.   gluBeginSurface(theNurbs);
  282.   gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
  283.           4 * T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
  284.           T_ORDER, GL_MAP2_VERTEX_4);
  285.   gluEndSurface(theNurbs);
  286.  
  287.   glPopMatrix();
  288.  
  289.   glFlush();
  290.  
  291.   if (doubleBuffer) {
  292.     tkSwapBuffers();
  293.   }
  294. }
  295.  
  296. static GLenum Args(int argc, char **argv)
  297. {
  298.   GLint i;
  299.  
  300.   doubleBuffer = GL_FALSE;
  301.   directRender = GL_TRUE;
  302.  
  303.   for (i = 1; i < argc; i++) {
  304.     if (strcmp(argv[i], "-sb") == 0) {
  305.       doubleBuffer = GL_FALSE;
  306.     }
  307.     else if (strcmp(argv[i], "-db") == 0) {
  308.       doubleBuffer = GL_TRUE;
  309.     }
  310.     else if (strcmp(argv[i], "-dr") == 0) {
  311.       directRender = GL_TRUE;
  312.     }
  313.     else if (strcmp(argv[i], "-ir") == 0) {
  314.       directRender = GL_FALSE;
  315.     }
  316.     else {
  317.       printf("%s (Bad option).\n", argv[i]);
  318.       return GL_FALSE;
  319.     }
  320.   }
  321.   return GL_TRUE;
  322. }
  323.  
  324. void main(int argc, char **argv)
  325. {
  326.   GLenum type;
  327.  
  328.   if (Args(argc, argv) == GL_FALSE) {
  329.     tkQuit();
  330.   }
  331.  
  332.   tkInitPosition(0, 0, 300, 300);
  333.  
  334.   type = TK_RGB;
  335.   type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  336.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  337.   tkInitDisplayMode(type);
  338.  
  339.   if (tkInitWindow("NURBS Test") == GL_FALSE) {
  340.     tkQuit();
  341.   }
  342.  
  343.   Init();
  344.  
  345.   tkExposeFunc(Reshape);
  346.   tkReshapeFunc(Reshape);
  347.   tkKeyDownFunc(Key);
  348.   tkDisplayFunc(Draw);
  349.   tkExec();
  350. }
  351.